package com.kedacom.demo.cometd;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.servlet.ServletContext;

import org.cometd.annotation.ServerAnnotationProcessor;
import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.server.BayeuxServerImpl;
import org.cometd.server.Jackson2JSONContextServer;
import org.cometd.server.transport.JSONPTransport;
import org.cometd.server.transport.JSONTransport;
import org.cometd.websocket.server.WebSocketTransport;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ServletContextAware;

@Component
public class Configurer implements DestructionAwareBeanPostProcessor, ServletContextAware {

	private BayeuxServer bayeuxServer;
	private ServerAnnotationProcessor processor;

	private ServletContext servletContext;

	@Inject
	private void setBayeuxServer(BayeuxServer bayeuxServer) {
		this.bayeuxServer = bayeuxServer;
	}

	@PostConstruct
	private void init() {
		this.processor = new ServerAnnotationProcessor(bayeuxServer);
	}

	public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
		processor.processDependencies(bean);
		processor.processConfigurations(bean);
		processor.processCallbacks(bean);
		return bean;
	}

	public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
		return bean;
	}

	public void postProcessBeforeDestruction(Object bean, String name) throws BeansException {
		processor.deprocessCallbacks(bean);
	}

	@Bean(initMethod = "start", destroyMethod = "stop")
	public BayeuxServer bayeuxServer() {
		BayeuxServerImpl bayeuxServer = new BayeuxServerImpl();
		Map<String, Object> options = new HashMap<String, Object>();
		options.put("ws.cometdURLMapping", "/cometd/*");
		// map.put("cometdURLMapping", "/cometd/*");
		options.put("maxSessionsPerBrowser", "-1");
		options.put("allowMultiSessionsNoBrowser", true);
		options.put("javax.servlet.ServletContext", servletContext);
		options.put("jsonContext", Jackson2JSONContextServer.class.getName());
		bayeuxServer.setOptions(options);
		bayeuxServer.setTransports(new WebSocketTransport(bayeuxServer), new JSONTransport(bayeuxServer), new JSONPTransport(bayeuxServer));
		return bayeuxServer;
	}

	@Override
	@Resource
	public void setServletContext(ServletContext servletContext) {
		this.servletContext = servletContext;
		servletContext.setAttribute(BayeuxServer.ATTRIBUTE, bayeuxServer);
	}

}
